﻿//
// *************************************************************************************
// WP-Framework
//
// Developed by 
// Lukas Kretschmar (lkretschmar.dev@bluewin.ch)
//
// Switzerland, Copyright (c) 2013 lkretschmar
// This content is released under the MIT License (http://opensource.org/licenses/MIT).
//     
// *************************************************************************************
//
//
			

using System;
using Expression = System.Linq.Expressions.Expression;
using KretschIT.WP_Fx.Core.Validation;
using KretschIT.WP_Fx.EasyMoq.Calls.Arguments;

namespace KretschIT.WP_Fx.EasyMoq.Matchers
{
    internal abstract class BaseMatcher<TExpression> : IMatcher where TExpression : Expression
    {
        public BaseMatcher(TExpression expression)
        {
            It.IsNotNull(() => expression);
            this.Validate(expression);
            this.MatcherExpression = expression;
        }

        protected virtual void Validate(TExpression expression) { }

        protected TExpression MatcherExpression { get; private set; }

        public bool Matches(IArgument arg)
        {
            return this.IsArgument(arg)
                && this.CompareType(arg.Type)
                && this.CompareValue(arg.Value);
        }

        protected virtual bool IsArgument(IArgument arg)
        {
            return arg != null;
        }

        protected virtual bool CompareType(Type type)
        {
            return this.AreEqual(type) || this.IsAssignable(type);
        }

        private bool AreEqual(Type type)
        {
            return this.MatcherExpression.Type == type;
        }
        
        private bool IsAssignable(Type type)
        {
            return type.IsAssignableFrom(this.MatcherExpression.Type);
        }

        protected abstract bool CompareValue(object value);
    }
}
